package com.young.ums.service.impl;

import com.young.common.exception.BaseException;
import com.young.common.util.CommonUtil;
import com.young.common.core.dal.service.IDataAccessService;
import com.young.common.util.Page;
import com.young.common.util.StringUtils;
import com.young.interfaces.log.annotation.Log;
import com.young.ums.core.ETopic;
import com.young.ums.core.ISubscriber;
import com.young.ums.model.Button;
import com.young.ums.model.RoleButton;
import com.young.ums.service.IButtonService;
import com.young.ums.service.IRoleButtonService;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 角色按钮关联信息服务实现
* Created by imrookie on 2018-11-3.
*/
@Service("roleButtonService")
public class RoleButtonServiceImpl implements IRoleButtonService,ISubscriber {

    @Resource(name = "dataAccessService")
    IDataAccessService dataAccessService;//数据层服务

    @Resource(name="buttonService")
    IButtonService buttonService;

    private static final Logger logger = LoggerFactory.getLogger(RoleButtonServiceImpl.class);

    private static final String MAPPER = "com.young.ums.mapper.roleButton";//mapper的namespace

    //获取数据列表
    @Log("查询角色按钮关系列表")
    @Override
    public List<RoleButton> getList(RoleButton obj) {
        return dataAccessService.getList(MAPPER + ".getList", obj);
    }

    //获取数据列表(分页)
    @Log("分页查询角色按钮关系列表")
    @Override
    public List<RoleButton> getPage(RoleButton obj, Page page) {
        return dataAccessService.getList(MAPPER + ".getList", obj, page);
    }

    //查询单条
    @Log("查询角色按钮关系")
    @Override
    public RoleButton get(String id) {
        return dataAccessService.getObject(MAPPER + ".get", id);
    }

    //统计数量
    @Log("统计角色按钮关系数量")
    @Override
    public int count(RoleButton obj) {
        return dataAccessService.getObject(MAPPER + ".count", obj);
    }

    //修改
    @Log("修改角色按钮关系")
    @Override
    public int update(RoleButton obj) {
        return dataAccessService.update(MAPPER + ".update", obj);
    }

    //批量删除
    @Log("批量删除角色按钮关系")
    @Override
    public int delete(String[] idArr) {
        int i = 0;
        for(String id : idArr){
            i += this.delete(id);
        }
        return i;
    }

    //删除单条
    @Log("删除角色按钮关系")
    @Override
    public int delete(String id) {
        return dataAccessService.delete(MAPPER + ".delete", id);
    }

    /**
     * 删除角色相关的所有关联信息
     *
     * @param roleId 角色id
     * @return
     */
    @Log("删除角色相关的所有关联关系")
    @Override
    public int deleteByRoleId(String roleId) {
        return dataAccessService.delete(MAPPER + ".deleteByRoleId", roleId);
    }

    /**
     * 删除按钮相关联的所有关联信息
     *
     * @param buttonId 按钮id
     * @return
     */
    @Log("删除按钮相关联的所有关联信息")
    @Override
    public int deleteByButtonId(String buttonId) {
        return dataAccessService.delete(MAPPER + ".deleteByButtonId", buttonId);
    }

    //插入
    @Log("插入角色按钮关系")
    @Override
    public int insert(RoleButton obj) {
        if (StringUtils.isBlank(obj.getId())){
            obj.setId(CommonUtil.getUUID());
        }
        return dataAccessService.insert(MAPPER + ".insert", obj);
    }

    //批量插入
    @Log("批量插入角色按钮关系")
    @Override
    public int batchInsert(List<RoleButton> list) {
        int i = 0;
        for(RoleButton item : list){
            i += this.insert(item);
        }
        return i;
    }

    /**
     * 批量关联按钮(N)到角色(1)
     *
     * @param roleId    角色id
     * @param buttonIds 按钮id数组
     * @return
     */
    @Log("批量关联按钮(N)到角色(1)")
    @Override
    public int relevanceButtons2Role(String roleId, String[] buttonIds) {
        int i = 0;
        if (StringUtils.isBlank(roleId)){
            logger.error("[授权] 角色id为空");
            throw new BaseException("角色ID不允许为空");
        }
        //先删除原有关联
        this.deleteByRoleId(roleId);
        if (buttonIds != null && buttonIds.length > 0){
            for (String buttonId : buttonIds){
                RoleButton roleButton = new RoleButton();
                roleButton.setRoleId(roleId);
                roleButton.setButtonId(buttonId);
                i += this.insert(roleButton);//插入关联关系
            }
        }
        return i;
    }

    /**
     * 判断指定角色和按钮是否存在关联
     *
     * @param roleId   角色id
     * @param buttonId 按钮id
     * @return
     */
    @Log("判断指定角色和按钮是否存在关联")
    @Override
    public boolean isRelevanced(String roleId, String buttonId) {
        RoleButton roleButton = new RoleButton();
        roleButton.setRoleId(roleId);
        roleButton.setButtonId(buttonId);
        return this.count(roleButton) > 0;
    }

    /**
     * 获取按钮授权树
     *
     * @param roleId 角色id
     * @return
     */
    @Log("获取按钮授权树")
    @Override
    public List<Button> getButtonListAboutGrantAuth(String roleId) {
        //查询按钮
        List<Button> list = buttonService.getList(null);
        //查询角色已关联的按钮
        List<String> buttonIds = this.getButtonIdsByRoleId(roleId);
        //若存在已关联按钮,在list上进行标记
        if (buttonIds != null && buttonIds.size() > 0){
            //数组转为map,使用hash来判断是否存在,优化效率
            Map<String, String> map = new HashMap<String, String>(buttonIds.size());
            for (String bid : buttonIds){
                map.put(bid, "1");
            }
            //遍历按钮进行标记
            for (Button button : list){
                if (button != null && map.containsKey(button.getId())){//存在关联关系
                    button.setChecked(true);
                }
            }
        }
        return list;
    }

    /**
     * 根据角色id查询相关联的按钮id集合
     *
     * @param roleId 角色id
     * @return
     */
    @Log("根据角色id查询相关联的按钮id集合")
    @Override
    public List<String> getButtonIdsByRoleId(String roleId) {
        return dataAccessService.getList(MAPPER + ".getButtonIdsByRoleId", roleId);
    }

    /**
     * 根据角色id数组批量查询相关联的按钮id集合
     *
     * @param roleIds
     * @return
     */
    @Log("根据角色id数组批量查询相关联的按钮id集合")
    @Override
    public List<String> getButtonIdsByRoleIds(String[] roleIds) {
        return dataAccessService.getList(MAPPER + ".getButtonIdsByRoleIds", roleIds);
    }

    /**
     * 根据按钮编号集合批量查询关联的角色编号
     *
     * @param buttonIds
     * @return
     */
    @Log("根据按钮编号集合批量查询关联的角色编号")
    @Override
    public List<String> getRoleIdsByButtonIds(List<String> buttonIds) {
        return dataAccessService.getList(MAPPER + ".getRoleIdsByButtonIds", buttonIds);
    }

    /**
     * 返回订阅的主题数组
     */
    @Override
    public ETopic[] topics() {
        return new ETopic[]{ETopic.ROLE_DEL, ETopic.BUTTON_DEL};
    }

    /**
     * 消费
     *
     * @param topic   主题
     * @param message 传输对象
     */
    @Override
    public void consume(ETopic topic, Object message) {
        try {
            if (topic == ETopic.ROLE_DEL){
                this.deleteByRoleId(message.toString());
            }else if (topic == ETopic.BUTTON_DEL){
                this.deleteByButtonId(message.toString());
            }
        } catch (Exception e) {
            logger.info("[UMS消息消费-RoleButtonServiceImpl] 消费异常,主题={},消息={}", topic, message, e);
            throw new BaseException(e);
        }
    }
}